#include<iostream>
#include<functional>
int f(int a,int b)//普通的全局函数
{
    return a + b;
}
struct Functor
{
    int operator()(int a, int b)//仿函数
    {
        return a + b;
    }
};
class Plus
{
    public:
        Plus(int n = 10)
        :_n(n){std::cout << "调用构造" << std::endl;}
        static int plusi(int a , int b)//静态全局函数
        {
            return a + b;
        }
        double plusd(double a,double b)//类的成员函数(隐藏参数this指针)
        {
            return (a + b) * _n;
        }
    private:
        int _n;
};
int main()
{
    //包装各种的可调用对象(个人感觉function的参数是上层的,与底层调用的函数不是强相关的,可以转换的类型会默认转换)
    std::function<int(int,int)> f1 = f;//封装普通函数
    std::function<int(int,int)> f2 = Functor();//封装仿函数
    std::function<int(int,int)>f3 = [](int a,int b)->int{return a + b;};

    std::cout << f1(1,1) << std::endl;
    std::cout << f2(1,1) << std::endl;
    std::cout << f3(1.1,1.9) << std::endl;

    //包装静态成员函数,成员函数要指定类域并且前面加&才能获取地址
    std::function<int(int,int)> f4 = &Plus::plusi;


    //包装成员函数不要忘记隐藏的this指针(因为底层要这个this指针会进行调用成员函数,所以传对象和地址都没有区别,只不过是使用运算符的差异)
    std::function<double(Plus*,double,double)> f5 = &Plus::plusd;
    Plus ps;
    std::cout << f5(&ps,1.2,3.9) << std::endl;

    std::function<double(Plus,double,double)> f6 = &Plus::plusd;
    std::cout << f6(ps,1,2) << std::endl;

    return 0;
}